package com.xiaobaibai.security;

import com.xiaobaibai.common.UserCommon;
import com.xiaobaibai.security.handler.HttpFailureHandler;
import com.xiaobaibai.security.handler.globalErrorHandler.SimpleAccessDeniedHandler;
import com.xiaobaibai.security.handler.globalErrorHandler.SimpleAuthenticationEntryPoint;
import com.xiaobaibai.security.handler.TokenSuccessHandler;
import com.xiaobaibai.security.master_token.config.No2TokenConfig;
import com.xiaobaibai.security.master_token.provider.JwtAuthenticationProvider;
import com.xiaobaibai.service.ITokenService;
import com.xiaobaibai.service.IUserAdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.header.Header;
import org.springframework.security.web.header.writers.StaticHeadersWriter;

import java.util.Arrays;

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private ITokenService tokenService;

    @Autowired
    private TokenSuccessHandler tokenSuccessHandler;

    @Autowired
    private HttpFailureHandler httpFailureHandler;

    @Bean//密码加密类(每次的盐都会不一样,但是都会匹配)
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Bean
    public JwtAuthenticationProvider jwtAuthenticationProvider(){
        return new JwtAuthenticationProvider(tokenService);
    }

    @Value("${excludeUri}")
    private String excludeUri;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
//                .antMatchers("/**").permitAll()

                .antMatchers("/swagger-ui.html").permitAll()
                .antMatchers("/webjars/**").permitAll()
                .antMatchers("/v2/**").permitAll()
                .antMatchers("/swagger-resources/**").permitAll()
                //公告不拦截
                .antMatchers("/announcement/**").permitAll()
                //分类不拦截
                .antMatchers("/category/**").permitAll()
                //首页基本数据不拦截+查看商品评价不拦截+根据分类查商品不拦截
                .antMatchers("/index/base-index","/product/evaluation/**","/product/product/by-category/**").permitAll()
                //搜索不拦截
                .antMatchers("/search/**").permitAll()
                //webStock不拦截
                .antMatchers("/imserver/**").permitAll()
                //支付回调不拦截
                .antMatchers("/pay/payNotifyUrl").permitAll()
                .antMatchers("/user/login").permitAll()//会自动加项目全局url前缀
                .antMatchers("/**").hasAnyAuthority(UserCommon.userRole)
                .anyRequest().authenticated()

                .and()
                .csrf().disable()//CRSF禁用，因为不使用session
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)//禁用session
        .and()
        .formLogin().disable() //禁用form登录
        .cors()//支持跨域
        .and()
        .headers().addHeaderWriter(new StaticHeadersWriter(Arrays.asList(
        new Header("Access-control-Allow-Origin","*"),
        new Header("Access-Control-Expose-Headers","Authorization"))))
        .and()
                .apply(new No2TokenConfig<>(excludeUri,httpFailureHandler)).tokenSuccessHandler(tokenSuccessHandler).setJwtAuthenticationProvider(jwtAuthenticationProvider())
        .and()
            .exceptionHandling()
                .accessDeniedHandler(new SimpleAccessDeniedHandler())
                .authenticationEntryPoint(new SimpleAuthenticationEntryPoint())
        ;
    }

}
